package com.ztn.iot.zhonghaichi2.fun;

import com.ztn.base.util.common.HttpClientTool;
import com.ztn.base.util.common.IdTool;
import com.ztn.base.util.common.TimeTool;
import com.ztn.iot.zhonghaichi2.entity.IotDeviceEntity;
import com.ztn.iot.zhonghaichi2.entity.SiteEntity;
import com.ztn.iot.zhonghaichi2.properties.ZhcProperties;
import com.ztn.iot.zhonghaichi2.properties.ZhcProperties2;
import com.ztn.iot.zhonghaichi2.push.DataPushApi;
import com.ztn.iot.zhonghaichi2.push.req.DataReq;
import com.ztn.iot.zhonghaichi2.push.req.PptnsData;
import com.ztn.iot.zhonghaichi2.push.req.RsvrsData;
import com.ztn.iot.zhonghaichi2.push.req.SeepagesData;
import com.ztn.iot.zhonghaichi2.push2.DataPushApi2;
import com.ztn.iot.zhonghaichi2.push2.TokenUtil;
import com.ztn.iot.zhonghaichi2.push2.req.DataReq2;
import com.ztn.iot.zhonghaichi2.service.IIotDeviceService;
import com.ztn.iot.zhonghaichi2.service.ISiteService;
import com.ztn.sdk.iot.api.IotDeviceExplainTool;
import com.ztn.sdk.iot.api.IotDeviceParamTool;
import com.ztn.sdk.iot.api.req.DeviceExplainListReq;
import com.ztn.sdk.iot.api.req.DeviceParamListReq;
import com.ztn.sdk.iot.api.res.DeviceExplain;
import com.ztn.sdk.iot.api.res.DeviceParam;
import com.ztn.sdk.iot.api.util.JsonTool;
import com.ztn.sdk.iot.hook.HookTool;
import com.ztn.sdk.iot.hook.bean.IotSystemHookWarp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeoutException;

@Slf4j
@Component
@EnableScheduling
public class SensorFun {

    @Autowired
    private ISiteService siteService;

    @Autowired
    private IIotDeviceService iotDeviceService;

//    @Autowired
//    private DataPushApi dataPushApi;

//    @Autowired
//    private TokenGetApi tokenGetApi;

    @Autowired
    private ZhcProperties zhcProperties;

    @Autowired
    private ZhcProperties2 zhcProperties2;


    public static final String EXPLAIN_KEY_NAME_RAIN = "eRainfall";
    public static final String EXPLAIN_KEY_NAME_WATER_DEPT = "eWDepth";
    public static final String EXPLAIN_KEY_NAME_WATER_DEPT2 = "eWaterLevel";
    public static final String EXPLAIN_KEY_NAME_SEEP_FLOW = "eSeepFlow";
    public static final String EXPLAIN_KEY_NAME_BIT_HIGH = "BitHigh";

    public static final String PARAM_KEY_NAME_SITE_STORAGE = "siteStorage";
    public static final String PARAM_KEY_NAME_SITE_CODE = "siteCode";
    public static final String PARAM_KEY_NAME_WARN_WATER_DEPT = "warnWaterDept";

    public static final String PARAM_KEY_NAME_DEFAULT_WATER_DEPT = "defaultEWDepth";
    public static final String PARAM_KEY_NAME_DEFAULT_SEEP_RATIO = "defaultSeepRatio";
    public static final String PARAM_KEY_NAME_DEFAULT_RAIN = "defaultRainfall";

    public static final String PARAM_KEY_NAME_DEVICE_ID = "deviceId";
    public static final String PARAM_KEY_NAME_DEVICE_SECRET = "devicePassword";
    public static final String PARAM_KEY_NAME_CAMERA_SIP = "cameraSip";

    private List<IotDeviceEntity> iotDeviceEntityListTemp = new ArrayList<>();

    public static final Integer TIME_TYPE_UN_KNOW = 0;
    public static final Integer TIME_TYPE_DAY = 1;
    public static final Integer TIME_TYPE_HOUR = 2;

    //创建一个EL解析器
    ExpressionParser parser = new SpelExpressionParser();
    TemplateParserContext templateParserContext = new TemplateParserContext("${", "}");


    @PostConstruct
    public void init() {
        log.info(JsonTool.toJson(zhcProperties));
//        HttpTool.setToken(zhcProperties.getIotApiToken());
//        updateToken();
        m15Job();
        new Thread(() -> {
            HookTool.IS_DURABLE = false;
            HookTool hookRabbit = new HookTool();
            try {
                hookRabbit.connect(zhcProperties.getIotMqTopic(), this::handler); //"exchange.zhonghaichi"
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }).start();
    }

//    @Scheduled(cron = "0 0/20 * * * ? ")
//    public void updateTokenJob() {
//        log.info("updateTokenJob()");
//        updateToken();
//    }
//
//    public void updateToken() {
////        TokenGetReq req = new TokenGetReq();
////        req.setUsername("赫章中海驰安防科技有限公司");
////        req.setUsercode("0547c53805f036b75d238a24d12e0e3c");
//        tokenGetApi.getToken();
//    }

    /**
     * 每一个小时
     */
    @Scheduled(cron = "0 0 0/1 * * ? ")
    public void hourJob() {
        log.info("hourJob");
        new Thread(() -> {
            siteService.list().forEach(siteEntity -> {
                try {
                    doJob(siteEntity);
                } catch (Exception e) {
                    log.error("", e);
                }
            });
            iotDeviceEntityListTemp.forEach(deviceEntity -> {
                try {
                    renewDeviceInfo(deviceEntity.getDeviceCore(), TIME_TYPE_HOUR);
                } catch (Exception e) {
                    log.error("", e);
                }

            });
        }).start();
    }

    /**
     * 每天8点
     */
    @Scheduled(cron = "0 0 8 * * ? ")
    public void dayJob() {
        log.info("dayJob");
        new Thread(() -> {
            siteService.list().forEach(siteEntity -> {
                try {
                    doJob(siteEntity);
                } catch (Exception e) {
                    log.error("", e);
                }
            });
            iotDeviceEntityListTemp.forEach(deviceEntity -> {
                try {
                    renewDeviceInfo(deviceEntity.getDeviceCore(), TIME_TYPE_DAY);
                } catch (Exception e) {
                    log.error("", e);
                }

            });
        }).start();
    }

    @Scheduled(cron = "0 0/15 * * * ? ")
    public void m15Job() {
        log.info("m15Job");
        new Thread(() -> {
            iotDeviceEntityListTemp = iotDeviceService.listAll();
        }).start();

    }


    void doJob(SiteEntity siteEntity) {
        if (!StringUtils.hasText(siteEntity.getSiteCode())) {
            return;
        }
        BigDecimal bdLastDayRainCount = BigDecimal.valueOf(siteEntity.getLastDayRainCount());
        BigDecimal bdLastHourRainCount = BigDecimal.valueOf(siteEntity.getLastHourRainCount());
        BigDecimal bdRainCount = BigDecimal.valueOf(siteEntity.getRainCount());

        final double rainCount = bdRainCount.doubleValue();
        final double lastHourRainCount = bdLastHourRainCount.doubleValue();
        final double lastDayRainCount = bdLastDayRainCount.doubleValue();

        int time = TimeTool.time();
        final String date = TimeTool.timeStamp2Date(time);
//        dataPushApi.pushRain(time, siteEntity.getSiteCode(), rainCount - lastRainCount, rainCount - lastHourRainCount, rainCount - lastDayRainCount);
        DataReq.Item item = new DataReq.Item();
        item.setPptn(Arrays.asList(PptnsData.builder()
                        .drp(rainCount - lastHourRainCount < 0 ? 0 : rainCount - lastHourRainCount)
                        .intv(1.00)
                        .stcd(siteEntity.getSiteCode())
                        .tm(date)
                        .dyp(rainCount - lastDayRainCount < 0 ? 0 : rainCount - lastDayRainCount)
//                .pdr()
                        .build()
        ));
//        dataPushApi.pushWater(time, siteEntity.getSiteCode(), siteEntity.getWaterDept(), siteEntity.getSiteStorage(), null, null, siteEntity.getWarnWaterDept());
        item.setRsvr(Arrays.asList(RsvrsData.builder()
                        .stcd(siteEntity.getSiteCode())
                        .tm(date)
                        .rz(siteEntity.getWaterDept() < 0 ? 0 : siteEntity.getWaterDept())
//                        .inq(input)
                        .w(siteEntity.getSiteStorage())
                        .blrz(siteEntity.getWaterDept() < 0 ? 0 : siteEntity.getWaterDept())
//                        .otq(output)
                        .rwchrcd(5)
                        .rwptn(6)
//                .inqdr()
                        .msqmt(4).build()
        ));
        if (siteEntity.getSiteStorage().equals(0)) {
//            dataPushApi.pushFlow(time, siteEntity.getSiteCode(), 0D, siteEntity.getWaterFlow(), siteEntity.getWarnWaterDept(), null);
            item.setSeepage(Arrays.asList(SeepagesData.builder()
                            .stcd(siteEntity.getSiteCode())
                            .tm(date)
                            .q(siteEntity.getWaterFlow().doubleValue() < 0 ? 0 : siteEntity.getWaterFlow().doubleValue())
                            .z(siteEntity.getWarnWaterDept())
//                .p()
                            .build()
            ));
        } else {
//            dataPushApi.pushFlow(time, siteEntity.getSiteCode(), null, siteEntity.getWaterFlow(), siteEntity.getWarnWaterDept(), null);
            item.setSeepage(Arrays.asList(SeepagesData.builder()
                            .stcd(siteEntity.getSiteCode())
                            .tm(date)
                            .q(siteEntity.getWaterFlow().doubleValue() < 0 ? 0 : siteEntity.getWaterFlow().doubleValue())
                            .z(siteEntity.getWarnWaterDept())
//                .p()
                            .build()
            ));
        }

        DataReq.DataItem dataDataItem = new DataReq.DataItem();
        dataDataItem.setInsert(item);
        DataReq dataReq = new DataReq();
        dataReq.setTime(date);
        dataReq.setToken(zhcProperties.getToken());
        dataReq.setSysid(IdTool.getUUID());
        dataReq.setAdcd(zhcProperties.getAdcd());
        dataReq.setDatas(dataDataItem);
        String reqJson = JsonTool.toJson(dataReq);
        log.info(reqJson);
        String str = HttpClientTool.postJsonStrForStr(DataPushApi.URL, reqJson, null);
        log.info(str);


        //2

        iotDeviceEntityListTemp.stream().filter(iotDeviceEntity -> {
            return iotDeviceEntity.getSiteId().equals(siteEntity.getSiteId());
        }).forEach(iotDeviceEntity -> {
            if (!StringUtils.hasText(iotDeviceEntity.getDeviceId()) || !StringUtils.hasText(iotDeviceEntity.getDeviceSecret())) {
                return;
            }
            String deviceId = iotDeviceEntity.getDeviceId();
            String deviceSecret = iotDeviceEntity.getDeviceSecret();

            String resourceName = "products/" + zhcProperties2.getProductId() + "/devices/" + deviceId;
            String expirationTime = System.currentTimeMillis() / 1000 + 100 * 24 * 60 * 60 + "";
            String accessKey = deviceSecret;
            String token = null;
            try {
                token = TokenUtil.assembleToken(zhcProperties2.getVersion(), resourceName, expirationTime, zhcProperties2.getSignatureMethod(), accessKey);
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (null == token) {
                return;
            }


            Map<String, Object> header = new HashMap<>(3);
            header.put("token", token);

//            StatusReq2 statusReq2 = new StatusReq2();
//            statusReq2.setStatus(1);
//            statusReq2.setPid(String.valueOf(IdTool.getInt()));
//            statusReq2.setDevName(deviceId);
//            statusReq2.setProtocol(zhcProperties2.getProtocol());
//            String s1 = HttpClientTool.postJsonStrWithHeaderForStr(StatusReq2.URL, JsonTool.toJson(statusReq2), header, null);
//            log.info("{}",s1);


            long longTime = TimeTool.longTime();

            List<DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO> valueDTOList = new ArrayList<>();


            //lh时段降水量 1AH
            if (siteEntity.getRainCount() - siteEntity.getLastHourRainCount() >= 0) {
                DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO lastHourRainCountValue = new DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO();
                lastHourRainCountValue.setIdentifier("1AH");
                lastHourRainCountValue.setRawValue(String.valueOf(siteEntity.getRainCount() - siteEntity.getLastHourRainCount()));
                lastHourRainCountValue.setValue(siteEntity.getRainCount() - siteEntity.getLastHourRainCount());
                lastHourRainCountValue.setCollectTime(longTime);
                lastHourRainCountValue.setAddr(iotDeviceEntity.getDeviceCore());
                lastHourRainCountValue.setOther("3");
                lastHourRainCountValue.setEquipmentModel(iotDeviceEntity.getDeviceCore());
                lastHourRainCountValue.setDrawingNum("3");
                valueDTOList.add(lastHourRainCountValue);
            }


            //日降水量 1FH
            if (siteEntity.getRainCount() - siteEntity.getLastDayRainCount() >= 0) {
                DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO lastDayRainCountValue = new DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO();
                lastDayRainCountValue.setIdentifier("1FH");
                lastDayRainCountValue.setRawValue(String.valueOf(siteEntity.getRainCount() - siteEntity.getLastDayRainCount()));
                lastDayRainCountValue.setValue(siteEntity.getRainCount() - siteEntity.getLastDayRainCount());
                lastDayRainCountValue.setCollectTime(longTime);
                lastDayRainCountValue.setAddr(iotDeviceEntity.getDeviceCore());
                lastDayRainCountValue.setOther("2");
                lastDayRainCountValue.setEquipmentModel(iotDeviceEntity.getDeviceCore());
                lastDayRainCountValue.setDrawingNum("2");
                valueDTOList.add(lastDayRainCountValue);
            }


            //降水量累计值 26H
            if (siteEntity.getRainCount() >= 0) {
                DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO rainCountValue = new DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO();
                rainCountValue.setIdentifier("26H");
                rainCountValue.setRawValue(String.valueOf(siteEntity.getRainCount()));
                rainCountValue.setValue(siteEntity.getRainCount());
                rainCountValue.setCollectTime(longTime);
                rainCountValue.setAddr(iotDeviceEntity.getDeviceCore());
                rainCountValue.setOther("1");
                rainCountValue.setEquipmentModel(iotDeviceEntity.getDeviceCore());
                rainCountValue.setDrawingNum("1");
                valueDTOList.add(rainCountValue);
            }


            //水位 3BH
            if (siteEntity.getWaterDept() >= 0) {
                DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO waterDeptCountValue = new DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO();
                waterDeptCountValue.setIdentifier("3BH");
                waterDeptCountValue.setRawValue(String.valueOf(siteEntity.getWaterDept()));
                waterDeptCountValue.setValue(siteEntity.getWaterDept());
                waterDeptCountValue.setCollectTime(longTime);
                waterDeptCountValue.setAddr(iotDeviceEntity.getDeviceCore());
                waterDeptCountValue.setOther("1");
                waterDeptCountValue.setEquipmentModel(iotDeviceEntity.getDeviceCore());
                waterDeptCountValue.setDrawingNum("1");
                valueDTOList.add(waterDeptCountValue);
            }

            //渗流量 FF09H
            if (siteEntity.getWaterFlow().compareTo(BigDecimal.ZERO) >= 0) {
                DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO waterFlowCountValue = new DataReq2.ParamsDTO.CollectedDataDTO.ValueDTO();
                waterFlowCountValue.setIdentifier("FF09H");
                waterFlowCountValue.setRawValue(String.valueOf(siteEntity.getWaterFlow()));
                waterFlowCountValue.setValue(siteEntity.getWaterFlow().doubleValue());
                waterFlowCountValue.setCollectTime(longTime);
                waterFlowCountValue.setAddr(iotDeviceEntity.getDeviceCore());
                waterFlowCountValue.setOther("1");
                waterFlowCountValue.setEquipmentModel(iotDeviceEntity.getDeviceCore());
                waterFlowCountValue.setDrawingNum("1");
                valueDTOList.add(waterFlowCountValue);
            }

            //渗流压力 FF08H

            DataReq2.ParamsDTO.CollectedDataDTO collectedDataDTO = new DataReq2.ParamsDTO.CollectedDataDTO();
            collectedDataDTO.setValue(valueDTOList);

            DataReq2.ParamsDTO paramsDTO = new DataReq2.ParamsDTO();
            paramsDTO.setVersion(new DataReq2.ParamsDTO.VersionDTO("1.0"));
            paramsDTO.setTime(new DataReq2.ParamsDTO.TimeDTO(longTime));
            paramsDTO.setGatewayCode(new DataReq2.ParamsDTO.GatewayCodeDTO(deviceId));
            paramsDTO.setGatewayType(new DataReq2.ParamsDTO.GatewayTypeDTO("ROUT-300"));
            paramsDTO.setCollectedData(collectedDataDTO);

            DataReq2 dataReq2 = new DataReq2();
            dataReq2.setId(String.valueOf(IdTool.getInt()));
            dataReq2.setVersion("1.0");
            dataReq2.setParams(paramsDTO);

            String url = DataPushApi2.BASE_URL + "?topic=$sys/" + zhcProperties2.getProductId() + "/" + deviceId + "/thing/property/post&protocol=" + zhcProperties2.getProtocol();
            String resStr = JsonTool.toJson(dataReq2);
            String s = HttpClientTool.postJsonStrWithHeaderForStr(url, resStr, header, null);
            log.info("push {} res {}", iotDeviceEntity.getDeviceCore(), s);

        });

//        SiteEntity siteSave = new SiteEntity();
//        siteSave.setSiteId(siteEntity.getSiteId());
//        siteSave.setLastHourRainCount(siteEntity.getRainCount()< 0 ? 0 :siteEntity.getRainCount());
//        siteService.update(siteSave);
//

    }


    void renewDeviceInfo(String deviceCore, Integer timeType) {
        DeviceParamListReq req = new DeviceParamListReq();
        req.setDeviceCore(deviceCore);
        final List<DeviceParam> deviceParamList = IotDeviceParamTool.list(req);

        String siteCode = null;
        for (DeviceParam deviceParam : deviceParamList) {
            if (deviceParam.getKeyName().equals(PARAM_KEY_NAME_SITE_CODE)) {
                if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                    siteCode = deviceParam.getValue().toString();
                }
            }
        }

        SiteEntity siteDb;
        if (StringUtils.hasText(siteCode)) {
            siteDb = siteService.getBySiteCode(siteCode);
        } else {
            return;
        }

        SiteEntity siteSave = new SiteEntity();
        if (null == siteDb) {
            if (StringUtils.hasText(siteCode)) {
                log.info("try insert site {}", siteCode);
                siteSave.setSiteCode(siteCode);
                siteService.insert(siteSave);
                siteDb = siteService.getBySiteCode(siteCode);
            } else {
                log.error("{} site is not exist", siteCode);
                return;
            }
        }

        if (null == siteDb) {
            log.error("insert site error {}", siteCode);
            return;
        }

        Map<String, Object> map = new HashMap<>(16);


        siteSave.setSiteId(siteDb.getSiteId());
        DeviceExplainListReq deviceExplainListReq = new DeviceExplainListReq();
        deviceExplainListReq.setDeviceCore(deviceCore);
        final List<DeviceExplain> deviceExplainList = IotDeviceExplainTool.list(deviceExplainListReq);
        deviceExplainList.forEach(sensorExplain -> {
            try {
                switch (sensorExplain.getKeyName()) {
                    case EXPLAIN_KEY_NAME_RAIN:
                        if (null != sensorExplain.getValue() && StringUtils.hasText(sensorExplain.getValue().toString())) {
                            siteSave.setRainCount(Double.parseDouble(sensorExplain.getValue().toString().trim()));
                            map.put(EXPLAIN_KEY_NAME_RAIN, Double.parseDouble(sensorExplain.getValue().toString().trim()));
                        }
                        break;
                    case EXPLAIN_KEY_NAME_WATER_DEPT:
                        if (null != sensorExplain.getValue() && StringUtils.hasText(sensorExplain.getValue().toString())) {
                            siteSave.setWaterDept(Double.parseDouble(sensorExplain.getValue().toString().trim()) / 100);
                            map.put(EXPLAIN_KEY_NAME_WATER_DEPT, Double.parseDouble(sensorExplain.getValue().toString().trim()) / 100);
                        }
                        break;
                    case EXPLAIN_KEY_NAME_WATER_DEPT2:
                        if (null != sensorExplain.getValue() && StringUtils.hasText(sensorExplain.getValue().toString())) {
                            siteSave.setWaterDept(Double.parseDouble(sensorExplain.getValue().toString().trim()));
                            map.put(EXPLAIN_KEY_NAME_WATER_DEPT2, Double.parseDouble(sensorExplain.getValue().toString().trim()));
                        }
                        break;
                    case EXPLAIN_KEY_NAME_SEEP_FLOW:
                        if (null != sensorExplain.getValue() && StringUtils.hasText(sensorExplain.getValue().toString())) {
                            siteSave.setWaterFlow(new BigDecimal(sensorExplain.getValue().toString().trim()));
                            map.put(EXPLAIN_KEY_NAME_SEEP_FLOW, new BigDecimal(sensorExplain.getValue().toString().trim()));
                        }
                        break;
                    case EXPLAIN_KEY_NAME_BIT_HIGH:
                        if (null != sensorExplain.getValue() && StringUtils.hasText(sensorExplain.getValue().toString())) {
                            siteSave.setWaterFlow(new BigDecimal(sensorExplain.getValue().toString().trim()).divide(BigDecimal.valueOf(1000)).divide(BigDecimal.valueOf(1000)));
                            map.put(EXPLAIN_KEY_NAME_BIT_HIGH, new BigDecimal(sensorExplain.getValue().toString().trim()).divide(BigDecimal.valueOf(1000)).divide(BigDecimal.valueOf(1000)));
                        }
                        break;
                    default:
                }
            } catch (Exception e) {
                log.error("", e);
            }

        });

        String deviceId = null;
        String deviceSecret = null;
        String cameraSip = null;


        for (DeviceParam deviceParam : deviceParamList) {
            try {
                switch (deviceParam.getKeyName()) {
                    case PARAM_KEY_NAME_SITE_STORAGE:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            double val = Double.parseDouble(eval(siteSave.getSiteStorage(), map, deviceParam.getValue().toString().trim()));
                            siteSave.setSiteStorage(val);
                        }
                        break;
                    case PARAM_KEY_NAME_WARN_WATER_DEPT:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            double val = Double.parseDouble(eval(siteSave.getWarnWaterDept(), map, deviceParam.getValue().toString().trim()));
                            siteSave.setWarnWaterDept(val);
                        }
                        break;
                    case PARAM_KEY_NAME_DEFAULT_RAIN:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            double val = Double.parseDouble(eval(siteSave.getRainCount(), map, deviceParam.getValue().toString().trim()));
                            siteSave.setRainCount(val);
                        }
                        break;
                    case PARAM_KEY_NAME_DEFAULT_WATER_DEPT:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            double val = Double.parseDouble(eval(siteSave.getWaterDept(), map, deviceParam.getValue().toString().trim()));
                            siteSave.setWaterDept(val);
                        }
                        break;
                    case PARAM_KEY_NAME_DEFAULT_SEEP_RATIO:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            BigDecimal val = new BigDecimal(eval(siteSave.getWaterFlow(), map, deviceParam.getValue().toString().trim()));
                            siteSave.setWaterFlow(val);
                        }
                        break;
                    case PARAM_KEY_NAME_DEVICE_ID:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            deviceId = deviceParam.getValue().toString().trim();
                        }
                        break;
                    case PARAM_KEY_NAME_DEVICE_SECRET:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            deviceSecret = deviceParam.getValue().toString().trim();
                        }
                        break;
                    case PARAM_KEY_NAME_CAMERA_SIP:
                        if (null != deviceParam.getValue() && StringUtils.hasText(deviceParam.getValue().toString())) {
                            cameraSip = deviceParam.getValue().toString().trim();
                        }
                        break;
                    default:
                }
            } catch (Exception e) {
                log.error("", e);
            }

        }


        IotDeviceEntity iotDeviceEntity = iotDeviceService.getByDeviceCode(deviceCore);
        if (null == iotDeviceEntity) {
            IotDeviceEntity iotDeviceSave = new IotDeviceEntity();
            iotDeviceSave.setDeviceCore(deviceCore);
            iotDeviceSave.setSiteId(siteSave.getSiteId());
            iotDeviceSave.setDeviceId(deviceId);
            iotDeviceSave.setDeviceSecret(deviceSecret);
            iotDeviceSave.setCameraSip(cameraSip);
            iotDeviceService.insert(iotDeviceSave);
        } else {
            if (!iotDeviceEntity.getSiteId().equals(siteSave.getSiteId())) {
                IotDeviceEntity iotDeviceSave = new IotDeviceEntity();
                iotDeviceSave.setId(iotDeviceEntity.getId());
                iotDeviceSave.setSiteId(siteSave.getSiteId());
                iotDeviceService.update(iotDeviceSave);
            }
            if (null != deviceId && !iotDeviceEntity.getDeviceId().equals(deviceId)) {
                IotDeviceEntity iotDeviceSave = new IotDeviceEntity();
                iotDeviceSave.setId(iotDeviceEntity.getId());
                iotDeviceSave.setDeviceId(deviceId);
                iotDeviceService.update(iotDeviceSave);
            }
            if (null != deviceSecret && !iotDeviceEntity.getDeviceSecret().equals(deviceSecret)) {
                IotDeviceEntity iotDeviceSave = new IotDeviceEntity();
                iotDeviceSave.setId(iotDeviceEntity.getId());
                iotDeviceSave.setDeviceSecret(deviceSecret);
                iotDeviceService.update(iotDeviceSave);
            }
            if (null != cameraSip && !iotDeviceEntity.getCameraSip().equals(cameraSip)) {
                IotDeviceEntity iotDeviceSave = new IotDeviceEntity();
                iotDeviceSave.setId(iotDeviceEntity.getId());
                iotDeviceSave.setCameraSip(cameraSip);
                iotDeviceService.update(iotDeviceSave);
            }

        }


        if (timeType.equals(TIME_TYPE_HOUR)) {
            siteSave.setLastHourRainCount(siteSave.getRainCount());
        } else if (timeType.equals(TIME_TYPE_DAY)) {
            siteSave.setLastDayRainCount(siteSave.getRainCount());
        }

        siteService.update(siteSave);
//        siteDb = siteService.getBySiteCode(siteCode);
//        doJob(siteDb);

    }


    public static String eval(Object pre, Map<String, Object> map, String script) {
        if (script.matches("[0-9]*")) {
            return script;
        }
        if (null != pre) {
            script = pre + script;
        }
        try {
            ExpressionParser parser = new SpelExpressionParser();
            TemplateParserContext templateParserContext = new TemplateParserContext("${", "}");
            //设置动态参数
            StandardEvaluationContext context = new StandardEvaluationContext();
            MapAccessor propertyAccessor = new MapAccessor();
            context.setVariables(map);
            context.setPropertyAccessors(Arrays.asList(propertyAccessor));
            SpelExpression expression = (SpelExpression) parser.parseExpression("${" + script + "}", templateParserContext);
            expression.setEvaluationContext(context);
            return expression.getValue(map, String.class);
        } catch (Exception e) {
            log.error("", e);
        }
        return pre.toString();
    }

    public void handler(String topic, IotSystemHookWarp iotSystemHookWarp) {
        try {
            String deviceCore = iotSystemHookWarp.getDeviceCore();
            renewDeviceInfo(deviceCore, TIME_TYPE_UN_KNOW);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
